
__kernel void particleStep(	__global float4 *positions,
							__global float4 *velocities,
							__global float *age,
							const float timeStep,
							const float animationTime,
							const float lifeTime,
							const int resetSignal,
							const float4 origin,
							const int numParticles,
							__global float4 *eyespaceParticles,
							float4 mv1,
							float4 mv2,
							float4 mv3,
							float4 mv4
							) {
							
	uint threadID = get_global_id(0);
	
	if ( threadID >= numParticles ) 
		return;
	
	float4 myPosition = positions[threadID];
	float4 myVelocity = velocities[threadID];
	
	float fId = (float)threadID;
	
	const float random1 = 0.149483f;
	const float random2 = 0.894363f;
	const float random3 = 0.975764f;
	const float random4 = 0.136943f;
	const float random5 = 0.234657f;
	const float random6 = 0.962354f;

	float myLifeTime = lifeTime * ( 1.0f + 0.2f * native_sin(random1 * fId) );

	float cycleTime = fmod( animationTime, myLifeTime );
	int passed = fmod( animationTime + timeStep, myLifeTime ) < cycleTime;
	
	int reset	= resetSignal || passed || (myPosition.z > 0.0f);
	
	if ( reset ) {
	
		float r1 = 0.04f + 0.04f * native_sin(random2 * fId);
		float angle1 = random3 * fId;
		float r2 = 0.4f + 0.1f * native_sin( random4 * fId );
		float angle2 = random6 * fId;

		myPosition	= origin;
		
		myPosition.x += r1 * native_cos( angle1 );
		myPosition.y += r1 * native_sin( angle1 );
		myPosition.w = 1.0f;
			
		myVelocity.x = r2 * native_sin(angle2);
		myVelocity.y = r2 * native_cos(angle2);
		myVelocity.z = -0.9 - 0.4 * fabs( native_sin( random5 * fId ) );
		myVelocity.w = 0.0f;
		
	}
	else {
		myVelocity.z	+= timeStep;
		myPosition.x	+= myVelocity.x * timeStep;
		myPosition.y	+= myVelocity.y * timeStep;
		myPosition.z	+= myVelocity.z * timeStep;
	}
	
	age[threadID]			= fmod( animationTime, myLifeTime ) / myLifeTime;
	positions[threadID]		= myPosition;
	velocities[threadID]	= myVelocity;

	if ( threadID == 0 ) {
		myPosition.x = 1.0f;
		myPosition.y = 0.0f;
		myPosition.z = -1.0f;
		myPosition.w = 0.0f;
	}

	float4 eyespace;
	if ( myVelocity.z > 0.0f || myPosition.w == 0.0f ) {
		eyespace.x = mv1.x * myPosition.x + mv2.x * myPosition.y + mv3.x	* myPosition.z + mv4.x * myPosition.w;
		eyespace.y = mv1.y * myPosition.x + mv2.y * myPosition.y + mv3.y	* myPosition.z + mv4.y * myPosition.w;
		eyespace.z = mv1.z * myPosition.x + mv2.z * myPosition.y + mv3.z	* myPosition.z + mv4.z * myPosition.w;
	}
	else {
		eyespace.x = 1000.0f;
		eyespace.y = 1000.0f;
		eyespace.z = 1000.0f;
	}
	eyespace.w = myPosition.w < 0.01f ? 0.0f : 1.0f;
	
	eyespaceParticles[threadID] = eyespace;


}


